/**
 * Wihidum - Efficient Broker Hierarchy for Publish Subscribe Middleware
 *
 * License      :   Apache License 2.0
 * Home Page    :   http://code.google.com/p/wihidum/
 * Mailing List :   wihidum@googlegroups.com
 */

package lk.mrt.cse.wihidum.receiver;

import lk.mrt.cse.wihidum.processor.*;
import lk.mrt.cse.wihidum.util.WihidumConstants;
import org.apache.axiom.om.OMException;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.receivers.AbstractInOutMessageReceiver;
import org.apache.log4j.Logger;


/**
 * Entry point of the messages received to the service
 */
public class MessageReceiver
        extends AbstractInOutMessageReceiver
{

    private static final Logger logger = Logger.getLogger (MessageReceiver.class);
    private Processor getBrokerProcessor;
    private Processor insertBrokerProcessor;
    private Processor removeBrokerProcessor;
    private Processor getMessageTraceProcessor;
    private Processor setMessageTraceProcessor;
    private Processor changeTopologyProcessor;
    private Processor getNetworkMapProcessor;

    /**
     * Default contructor
     */
    public MessageReceiver()
    {
        getBrokerProcessor=new GetBrokerProcessor();
        insertBrokerProcessor = new InsertBrokerProcessor();
        removeBrokerProcessor = new RemoveBrokerProcessor();
        getMessageTraceProcessor = new GetMessageTraceProcessor();
        setMessageTraceProcessor = new SetMessageTraceProcessor();
        changeTopologyProcessor = new ChangeTopologyProcessor();
        getNetworkMapProcessor = new GetNetworkMapProcessor();
    }

    /**
     * Process the messages
     *
     * @param inMessage  Incoming message context
     * @param outMessage Outgoing message context
     * @throws org.apache.axis2.AxisFault Exception
     */
    public void invokeBusinessLogic (MessageContext inMessage, MessageContext outMessage)
            throws AxisFault
    {
        logger.info ("Admin service received a new message");

        try
        {
            Options opts=inMessage.getOptions();
            String action=opts.getAction();
            SOAPEnvelope requestEnvelop = inMessage.getEnvelope ();
            SOAPEnvelope responseEnvelope;

            if (action.equals (WihidumConstants.Operations.INSERT_BROKER))
            {
                logger.info ("Received message to Admin Service is an Insert Broker request");
                responseEnvelope = insertBrokerProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.INSERT_BROKER_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if (action.equals (WihidumConstants.Operations.REMOVE_BROKER))
            {
                logger.info ("Received message to Admin Service is a Remove Broker request");
                responseEnvelope = removeBrokerProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.REMOVE_BROKER_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if (action.equals (WihidumConstants.Operations.GET_MESSAGE_TRACE))
            {
                logger.info ("Received message to Admin Service is a Get Message Trace request");
                responseEnvelope = getMessageTraceProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.GET_MESSAGE_TRACE_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if (action.equals (WihidumConstants.Operations.SET_MESSAGE_TRACE))
            {
                logger.info ("Received message to Admin Service is a Set Message Trace request");
                responseEnvelope = setMessageTraceProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.SET_MESSAGE_TRACE_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if (action.equals (WihidumConstants.Operations.CHANGE_TOPOLOGY))
            {
                logger.info ("Received message to Admin Service is a Change Topology request");
                responseEnvelope = changeTopologyProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.CHANGE_TOPOLOGY_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if (action.equals (WihidumConstants.Operations.GET_NETWORK_MAP))
            {
                logger.info ("Received message to Admin Service is a Get Network Map Trace request");
                responseEnvelope = getNetworkMapProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.GET_NETWORK_MAP_RESPONSE);
                outMessage.setEnvelope (responseEnvelope);
                logger.info ("Received message processing complete");
            }
            else if(action.equals(WihidumConstants.Operations.GET_BROKER))
            {
                logger.info("Received message to Admin Service is a Get Broker request");
                responseEnvelope=getBrokerProcessor.processMessage(requestEnvelop);
                Options outOpts=outMessage.getOptions();
                outOpts.setAction(WihidumConstants.Operations.GET_BROKER_RESPONSE);
                outMessage.setEnvelope(responseEnvelope);
                
                
            }
            else
            {
                logger.info ("Received message to Broker Service is in unrecognized format");
            }
        }
        catch (NullPointerException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
        catch (OMException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
        catch (AxisFault ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
    }
}
